/*
    This file is part of QTau
    Copyright (C) 2013-2018  Tobias "Tomoko" Platen <tplaten@posteo.de>
    Copyright (C) 2013       digited       <https://github.com/digited>
    Copyright (C) 2010-2013  HAL@ShurabaP  <https://github.com/haruneko>

    QTau is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    SPDX-License-Identifier: GPL-3.0+
*/

#define __devloglevel__ 5
#include "audio/audioengine.h"
#include "PluginInterfaces.h"
#include "audio/jackaudio.h"

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/eventfd.h>
#include <unistd.h>

#include "../Controller.h"

AudioEngine::AudioEngine(JackAudio* jack, QObject* parent) : QThread(parent) {
  _jack = jack;
  _jack_buffer = _jack->allocateBuffer();
  _jack_buffer_size = _jack->getBufferSize();
  _eventfd = _jack->createEFD();
  _pos = 0;
  start();
}

void AudioEngine::shutdown() {
  _running = false;
  uint64_t u = 2;
  int ret = write(_eventfd, &u, sizeof(uint64_t));
  if (ret == 8) usleep(100);
}

void AudioEngine::run() {
  while (_running) {
    uint64_t u;
    int count = read(_eventfd, &u, sizeof(uint64_t));
    if (u == 1 && count == 8) {
      memset(_jack_buffer, 0, _jack_buffer_size * sizeof(float));

      bool isRolling;
      if (_useJackTransport)
        isRolling = _jack->isRolling();
      else
        isRolling = _localTransportRolling;

      if (isRolling) {
        // if(_scheduledSynth) {
        //    _scheduledSynth->readData(_jack_buffer,_jack_buffer_size);
        //}
        _outp->readData(_jack_buffer, _jack_buffer_size);

        _pos += _jack_buffer_size;
        if (_useJackTransport) _lastJackTransportPos = _pos;
      }

      if (_preview) _preview->readData(_jack_buffer, _jack_buffer_size);

      _jack->writeData(_jack_buffer, _jack_buffer_size * sizeof(float));
    }
  }
}
